﻿using System;
using System.Drawing;
using System.Windows.Forms;
using MediaController.Client.Controls.Properties;

namespace MediaController.Client.Controls.Dialogs
{
    /// <summary>
    /// 
    /// </summary>
    public enum MessageType
    {
        Help,
        Info,
        Warning,
        Error,
    }

    public partial class MessageForm : Form
    {
        #region Private Data

        /// <summary>
        /// 
        /// </summary>
        private bool _extendedDataShown;

        /// <summary>
        /// 
        /// </summary>
        private int _extendedDataShownSize;

        #endregion


        public MessageForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Show message form box.
        /// <div>use <see cref="MessageType.Error"/></div>
        /// <div>safe to call on non UI thread</div>
        /// </summary>
        /// <param name="exception">the extended data to show (can be null)</param>
        public static void ShowMessageFormException(Exception exception)
        {
            ShowMessageFormException(MessageType.Error, exception);
        }

        /// <summary>
        /// Show message form box.
        /// <div>use <see cref="MessageType.Error"/></div>
        /// <div>safe to call on non UI thread</div>
        /// </summary>
        /// <param name="message">the message to show (can be null)</param>
        /// <param name="exception">the extended data to show (can be null)</param>
        public static void ShowMessageFormException(string message, Exception exception)
        {
            ShowMessageFormException(MessageType.Error, message, exception);
        }

        /// <summary>
        /// Show message form box.
        /// <div>safe to call on non UI thread</div>
        /// </summary>
        /// <param name="messageType">the message type to effect appearance</param>
        /// <param name="exception">the extended data to show (can be null)</param>
        public static void ShowMessageFormException(MessageType messageType, Exception exception)
        {
            ShowMessageForm(messageType, exception != null ? exception.Message : null, exception != null ? exception.ToString() : null);
        }

        /// <summary>
        /// Show message form box.
        /// <div>Adds the exception message to <paramref name="message"/></div>
        /// <div>safe to call on non UI thread</div>
        /// </summary>
        /// <param name="messageType">the message type to effect appearance</param>
        /// <param name="message">the message to show (can be null)</param>
        /// <param name="exception">the extended data to show (can be null)</param>
        public static void ShowMessageFormException(MessageType messageType, string message, Exception exception)
        {
            if (message != null)
            {
                if (exception != null)
                    message = string.Format("{0}{1}Error: {2}", message, Environment.NewLine, exception.Message);
            }

            ShowMessageForm(messageType, message, exception != null ? exception.ToString() : null);
        }

        /// <summary>
        /// Show message form box.
        /// <div>safe to call on non UI thread</div>
        /// </summary>
        /// <param name="messageType">the message type to effect appearance</param>
        /// <param name="message">the message to show (can be null)</param>
        /// <param name="exception">the extended data to show (can be null)</param>
        public static void ShowMessageFormExceptionNoMessage(MessageType messageType, string message, Exception exception)
        {
            ShowMessageForm(messageType, message, exception != null ? exception.ToString() : null);
        }

        /// <summary>
        /// Show message form box.
        /// <div>safe to call on non UI thread</div>
        /// </summary>
        /// <param name="messageType">the message type to effect appearance</param>
        /// <param name="message">the message to show (can be null)</param>
        public static void ShowMessageForm(MessageType messageType, string message)
        {
            ShowMessageForm(messageType, message, null);
        }

        /// <summary>
        /// Show message form box.
        /// <div>safe to call on non UI thread</div>
        /// </summary>
        /// <param name="messageType">the message type to effect appearance</param>
        /// <param name="message">the message to show (can be null)</param>
        /// <param name="extendedData">the extended data to show (can be null)</param>
        public static void ShowMessageForm(MessageType messageType, string message, string extendedData)
        {
            if (Application.OpenForms.Count > 0)
            {
                var openForm = Application.OpenForms[0];
                if (openForm.InvokeRequired)
                {
                    openForm.BeginInvoke(new MethodInvoker(() => ShowMessageFormInner(messageType, message, extendedData)));
                }
                else
                {
                    ShowMessageFormInner(messageType, message, extendedData);
                }
            }
            else
            {
                ShowMessageFormInner(messageType, message, extendedData);
            }
        }

        #region Private methods

        /// <summary>
        /// Show message form box.
        /// </summary>
        /// <param name="messageType">the message type to effect appearance</param>
        /// <param name="message">the message to show (can be null)</param>
        /// <param name="extendedData">the extended data to show (can be null)</param>
        private static void ShowMessageFormInner(MessageType messageType, string message, string extendedData)
        {
            var form = new MessageForm();
            form.SetMessageFormData(messageType, message, extendedData);
            form.ShowDialog(Application.OpenForms.Count > 0 ? Application.OpenForms[0] : null);
        }

        /// <summary>
        /// Set message data.
        /// </summary>
        /// <param name="messageType">the type of the message to show</param>
        /// <param name="message">the message to show (can be null)</param>
        /// <param name="extendedData">the extended data to show (can be null)</param>
        private void SetMessageFormData(MessageType messageType, string message, string extendedData)
        {
            if (string.IsNullOrEmpty(message))
                message = "NO MESSAGE";

            var orgMessage = message;
            if (message.Length > 40)
            {
                var idx = message.LastIndexOf(' ', 40);
                idx = idx > 0 ? idx : 40;
                message = message.Substring(0, idx) + "...";
            }
            SetMessageFormDataForType(message, messageType);

            _messageTB.Text = orgMessage;
            _okButton.Select();
            if (extendedData != null)
            {
                _extendedDataTB.Text = extendedData;
            }
            else
            {
                _showExtendedData.Visible = false;
            }
        }

        /// <summary>
        /// Set form data with respect to type
        /// </summary>
        /// <param name="messageType">the message type to show</param>
        /// <param name="message">the message string</param>
        private void SetMessageFormDataForType(string message, MessageType messageType)
        {
            switch (messageType)
            {
                case MessageType.Help:
                    _messageIconPB.Image = Resource.Information;
                    //Icon = MediaResource.Symbol_Help_ico;
                    Text = "Help: " + message;
                    break;
                case MessageType.Info:
                    _messageIconPB.Image = Resource.Information;
                    //Icon = MediaResource.Symbol_Information_ico;
                    Text = "Info: " + message;
                    break;
                case MessageType.Warning:
                    _messageIconPB.Image = Resource.Warning;
                    //Icon = MediaResource.Symbol_Exclamation_ico;
                    Text = "Warning: " + message;
                    break;
                case MessageType.Error:
                    _messageIconPB.Image = Resource.Error;
                    //Icon = MediaResource.Symbol_Error_ico;
                    Text = "Error: " + message;
                    break;
                default:
                    throw new ArgumentOutOfRangeException("messageType", "unknown value: " + messageType);
            }
        }

        /// <summary>
        /// Show the text box with the extended data.
        /// </summary>
        private void OnShowExtendedData_Click(object sender, EventArgs e)
        {
            _extendedDataShown = !_extendedDataShown;
            if (_extendedDataShown)
            {
                const int EXTEND_HEIGHT = 350;
                _extendedDataShownSize = Size.Height;
                Size = new Size(Size.Width, Math.Max(Size.Height, EXTEND_HEIGHT));
                _showExtendedData.Text = "Extended Data <<";

                _messageTB.Height = _messageIconPB.Height;
                _messageTB.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
                _extendedDataTB.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom;
                _extendedDataTB.Height = _okButton.Location.Y - _extendedDataTB.Location.Y - 9;
            }
            else
            {
                Size = new Size(Size.Width, _extendedDataShownSize);
                _showExtendedData.Text = "Extended Data >>";
                _messageTB.Height = _okButton.Location.Y - _messageTB.Location.Y - 9;
                _messageTB.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom;
                _extendedDataTB.Height = 0;
                _extendedDataTB.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
            }
            Invalidate();
        }

        private void OnOkButton_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void MessageForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.A)
            {
                _messageTB.SelectAll();
                _extendedDataTB.SelectAll();
            }
        }

        #endregion
    }
    partial class MessageForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this._messageIconPB = new System.Windows.Forms.PictureBox();
            this._messageTB = new System.Windows.Forms.TextBox();
            this._okButton = new System.Windows.Forms.Button();
            this._extendedDataTB = new System.Windows.Forms.TextBox();
            this._showExtendedData = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this._messageIconPB)).BeginInit();
            this.SuspendLayout();
            // 
            // _messageIconPB
            // 
            this._messageIconPB.Location = new System.Drawing.Point(12, 12);
            this._messageIconPB.Name = "_messageIconPB";
            this._messageIconPB.Size = new System.Drawing.Size(100, 100);
            this._messageIconPB.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            this._messageIconPB.TabIndex = 0;
            this._messageIconPB.TabStop = false;
            // 
            // _messageTB
            // 
            this._messageTB.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this._messageTB.Location = new System.Drawing.Point(118, 12);
            this._messageTB.Multiline = true;
            this._messageTB.Name = "_messageTB";
            this._messageTB.ReadOnly = true;
            this._messageTB.Size = new System.Drawing.Size(330, 100);
            this._messageTB.TabIndex = 1;
            // 
            // _okButton
            // 
            this._okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this._okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this._okButton.Location = new System.Drawing.Point(374, 118);
            this._okButton.Name = "_okButton";
            this._okButton.Size = new System.Drawing.Size(75, 23);
            this._okButton.TabIndex = 2;
            this._okButton.Text = "OK";
            this._okButton.UseVisualStyleBackColor = true;
            this._okButton.Click += new System.EventHandler(this.OnOkButton_Click);
            // 
            // _extendedDataTB
            // 
            this._extendedDataTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this._extendedDataTB.Location = new System.Drawing.Point(12, 117);
            this._extendedDataTB.Multiline = true;
            this._extendedDataTB.Name = "_extendedDataTB";
            this._extendedDataTB.ReadOnly = true;
            this._extendedDataTB.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this._extendedDataTB.Size = new System.Drawing.Size(436, 0);
            this._extendedDataTB.TabIndex = 3;
            // 
            // _showExtendedData
            // 
            this._showExtendedData.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this._showExtendedData.Location = new System.Drawing.Point(12, 118);
            this._showExtendedData.Name = "_showExtendedData";
            this._showExtendedData.Size = new System.Drawing.Size(122, 23);
            this._showExtendedData.TabIndex = 6;
            this._showExtendedData.Text = "Extended Data >>";
            this._showExtendedData.UseVisualStyleBackColor = true;
            this._showExtendedData.Click += new System.EventHandler(this.OnShowExtendedData_Click);
            // 
            // MessageForm
            // 
            this.AcceptButton = this._okButton;
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.CancelButton = this._okButton;
            this.ClientSize = new System.Drawing.Size(459, 150);
            this.Controls.Add(this._showExtendedData);
            this.Controls.Add(this._extendedDataTB);
            this.Controls.Add(this._okButton);
            this.Controls.Add(this._messageTB);
            this.Controls.Add(this._messageIconPB);
            this.KeyPreview = true;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.MinimumSize = new System.Drawing.Size(475, 186);
            this.Name = "MessageForm";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Message";
            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MessageForm_KeyDown);
            ((System.ComponentModel.ISupportInitialize)(this._messageIconPB)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.PictureBox _messageIconPB;
        private System.Windows.Forms.TextBox _messageTB;
        private System.Windows.Forms.Button _okButton;
        private System.Windows.Forms.TextBox _extendedDataTB;
        private System.Windows.Forms.Button _showExtendedData;

    }
}